home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS02.ADF / C / alib.c < prev    next >
C/C++ Source or Header  |  1989-05-30  |  11KB  |  397 lines

  1.  
  2. /*
  3.  * ALIB Rev. 1.0
  4.  * Amiga Object Module Librarian
  5.  * Programmed by Mike Schwartz
  6.  *               (C)1985, MS Software, all rights reserved.
  7.  *
  8.  * Feel free to distribute this program on a no-charge basis.
  9.  *
  10.  * Use:
  11.  *    ALIB  option  library filelist
  12.  * Where
  13.  *    option may be one of the following:
  14.  *       D  =  delete object modules from library
  15.  *       R  =  replace object modules (or add if not defined)
  16.  *       L  =  directory of library
  17.  *    library is the name of the library file to be created or modified.
  18.  *       if no .lib extension is provided on the command line, it is
  19.  *       appended.  Also note that a file library.dir is created for
  20.  *       each library file and is managed by this program.
  21.  *    filelist is a list of object module filenames separated by spaces
  22.  *       or commas.  Note that if .o is not present in the filenames,
  23.  *       .o will be appended.
  24.  */
  25. #include "stdio.h"
  26. #include "fcntl.h"
  27.  
  28. /*
  29.  * The following structure defines the records in the .dir file for
  30.  * the library.
  31.  */
  32. #define  LD    struct   libdir_def
  33. struct   libdir_def     {
  34.    char  object_filename[80];       /* name of .o file */
  35.    long  module_offset;             /* offset of module in .lib file */
  36.    long  module_size;               /* size of module in bytes */
  37.    };
  38.  
  39. /*
  40.  * When the library is openned, each object module is read into memory
  41.  * and managed with the following structure.
  42.  */
  43. #define  LL    struct   liblist_def
  44. struct   liblist_def    {
  45.    struct   libdir_def  dir_entry;  /* directory entry for module */
  46.    char     *object_module;         /* actual text of module */
  47.    LL       *next;                  /* pointer to next in list */
  48.    };
  49.  
  50. /*
  51.  * external functions
  52.  */
  53. extern   char  *getmem();
  54. extern   long  lseek();
  55.  
  56. /*
  57.  * Global variables
  58.  */
  59. LL    *objlist=NULL;                /* linked list of object modules */
  60.  
  61. char  libname[80];                  /* name of library file */
  62. int   libfd;                        /* file descriptor for library file */
  63. char  objname[80];                  /* name of object file */
  64. int   objfd;                        /* file descriptor for object file */
  65. char  dirname[80];                  /* name of directory file */
  66. int   dirfd;                        /* file descriptor for directory file */
  67.  
  68. char  buf[512];                     /* misc buffer */
  69.  
  70. char  option;                       /* user selected option */
  71. /*
  72.  * This function prints the help messages and exits.
  73.  */
  74. help() {
  75.    printf("Use:\n");
  76.    printf("   ALIB  option  library filelist \n");
  77.    printf("Where\n");
  78.    printf("   option may be one of the following:\n");
  79.    printf("      D  =  delete object modules from library\n");
  80.    printf("      R  =  replace object modules (or add if not defined) \n");
  81.    printf("      L  =  directory of library\n");
  82.    printf("   library is the name of the library file to be created or modified.\n");
  83.    printf("      if no .lib extension is provided on the command line, it is \n");
  84.    printf("      appended.  Also note that a file library.dir is created for\n");
  85.    printf("      each library file and is managed by this program. \n");
  86.    printf("   filelist is a list of object module filenames separated by spaces\n");
  87.    printf("      or commas.  Note that if .o is not present in the filenames, \n");
  88.    printf("      .o will be appended. \n");
  89.    exit(1);
  90.    }
  91.  
  92. /*
  93.  * The following function opens the library and directory file.  If the
  94.  * file does not exist, then the user is asked if he wants to create it.
  95.  * If the library exists, then it is read in and built in a linked list.
  96.  */
  97. open_library() {
  98.    LL    *lp;           /* pointer to module node */
  99.  
  100.    /*
  101.     * Open the library file and directory file.
  102.     */
  103.    libfd = open(libname, O_RDONLY | O_RAW);
  104.    if (libfd == -1) {
  105.       /*
  106.        * Library does not exist, prompt user for creation.
  107.        */
  108.       while (1) {
  109.          printf("%s does not exist, create it? (Y/N): ", libname);
  110.          gets(buf);
  111.          if (buf[0] == 'y' || buf[0] == 'Y')
  112.             return !0;
  113.          if (buf[0] == 'n' || buf[0] == 'N') {
  114.             printf("Alib abandoned\n");
  115.             exit(1);
  116.             }
  117.          }
  118.       }
  119.    dirfd = open(dirname, O_RDONLY | O_RAW);
  120.    if (dirfd == -1) {
  121.       printf("%s has been corrupted\n", dirname);
  122.       printf("Alib abandoned\n");
  123.       exit(1);
  124.       }
  125.    /*
  126.     * library and directory files are open, read in the library.
  127.     */
  128.    while (1) {
  129.       /*
  130.        * Allocate a node to hold the object module.
  131.        */
  132.       lp = (LL *)getmem(sizeof(LL));
  133.       if (lp == NULL) {
  134.          printf("Not enough memory.\nAlib abandoned\n");
  135.          exit(1);
  136.          }
  137.       /*
  138.        * Check for end of file.
  139.        */
  140.       if (read(dirfd, (char *)&lp->dir_entry, sizeof(LD)) != sizeof(LD))
  141.          break;
  142.       /*
  143.        * Allocate a buffer to hold the object file image.
  144.        */
  145.       lp->object_module = getmem(lp->dir_entry.module_size);
  146.       if (lp->object_module == NULL) {
  147.          printf("Not enough memory.\nAlib abandoned\n");
  148.          exit(1);
  149.          }
  150.       /*
  151.        * Read in the object module
  152.        */
  153.       if (read(libfd, lp->object_module, lp->dir_entry.module_size) != 
  154.                  lp->dir_entry.module_size) {
  155.          printf("Library file is corrupted.\nAlib abandoned\n");
  156.          exit(1);
  157.          }
  158.       /*
  159.        * Add module to linked list.
  160.        */
  161.       lp->next = objlist;
  162.       objlist = lp;
  163.       }
  164.    /*
  165.     * Library has been read in ok.  Close files and return.
  166.     */
  167.    close(libfd);
  168.    close(dirfd);
  169.    printf("Library file read in ok\n");
  170.    }
  171.  
  172. /*
  173.  * The following function removes an object module from the linked list
  174.  * and frees up any memory used by it.
  175.  */
  176. kill_module(name)
  177. char  *name;
  178. {
  179.    LL    *lp;
  180.    LL    *lp2;
  181.  
  182.    if (objlist == NULL)
  183.       return 0;
  184.    strcpy(objname, name);
  185.    strcat(objname, ".o");
  186.    if (strcmp(objlist->dir_entry.object_filename,  objname) == 0) {
  187.       lp = objlist->next;
  188.       rlsmem(objlist->object_module, objlist->dir_entry.module_size);
  189.       rlsmem((char *)objlist, sizeof(LL));
  190.       objlist = lp;
  191.       return !0;
  192.       }
  193.    for (lp = objlist; lp->next != NULL; lp=lp->next)
  194.       if (strcmp(lp->next->dir_entry.object_filename, objname) == 0) {
  195.          lp2 = lp->next;
  196.          lp->next = lp2->next;
  197.          rlsmem(lp2->object_module, lp2->dir_entry.module_size);
  198.          rlsmem((char *)lp2, sizeof(LL));
  199.          return !0;
  200.          }
  201.    return 0;
  202.    }
  203.  
  204. /*
  205.  * The following function
  206.  */
  207. add_module(name)
  208. char  *name;
  209. {
  210.    LL    *lp;
  211.    int   len;
  212.  
  213.    strcpy(objname, name);
  214.    strcat(objname, ".o");
  215. printf("adding %s\n", objname);
  216.  
  217.    /*
  218.     * Open the object file
  219.     */
  220.    objfd = open(objname, O_RDONLY | O_RAW);
  221.    if (objfd == -1) {
  222.       printf("%s cannot be added\nAlib abandoned\n", objname);
  223.       exit(1);
  224.       }
  225.    /*
  226.     * Allocate a node to hold the file.
  227.     */
  228.    lp = (LL *)getmem(sizeof(LL));
  229.    if (lp == NULL) {
  230.       printf("Not enough memory.\nAlib abandoned\n");
  231.       exit(1);
  232.       }
  233.    /*
  234.     * Initialize it.
  235.     */
  236.    strcpy(lp->dir_entry.object_filename, objname);
  237.    lp->dir_entry.module_size = lseek(objfd, 0, 2);
  238. printf("module size = %d\n", lp->dir_entry.module_size);
  239.    lseek(objfd, 0, 0);
  240.    /*
  241.     * Allocate the buffer to read the object module into.
  242.     */
  243.    lp->object_module = getmem(lp->dir_entry.module_size);
  244.    if (lp->object_module == NULL) {
  245.       printf("Not enough memory.\nAlib abandoned\n");
  246.       exit(1);
  247.       }
  248.    /*
  249.     * Read in the file.
  250.     */
  251.    if (read(objfd, lp->object_module, lp->dir_entry.module_size) != 
  252.              lp->dir_entry.module_size) {
  253.       printf("Library file is corrupted.\nAlib abandoned\n");
  254.       exit(1);
  255.       }
  256.    /*
  257.     * Add module to linked list.
  258.     */
  259.    lp->next = objlist;
  260.    objlist = lp;
  261.    /*
  262.     * Close object file and return.
  263.     */
  264.    close(objfd);
  265.    printf("%s added\n", name);
  266.    }
  267.  
  268. /*
  269.  * The following routine writes the library from memory and exits.
  270.  */
  271. close_library() {
  272.    LL    *lp;
  273.    long  file_position;
  274.    long  length;
  275.  
  276.    /*
  277.     * Open the library
  278.     */
  279.    libfd = open(libname, O_CREAT | O_RAW | O_WRONLY);
  280.    if (libfd == -1) {
  281.       printf("Error openning %s for output\nAlib abandoned", libname);
  282.       exit(1);
  283.       }
  284.    dirfd = open(dirname, O_CREAT | O_RAW | O_WRONLY);
  285.    if (dirfd == -1) {
  286.       printf("Error openning %s for output\nAlib abandoned", dirname);
  287.       exit(1);
  288.       }
  289.    /*
  290.     * Write out the individual modules and directory records.
  291.     */
  292.    file_position = 0;
  293.    for (lp = objlist; lp != NULL; lp = lp->next) {
  294.       length = write(libfd, lp->object_module, lp->dir_entry.module_size);
  295.       if (length != lp->dir_entry.module_size) {
  296.          printf("Error writing to library file\nAlib abandoned\n");
  297.          exit(1);
  298.          }
  299.       lp->dir_entry.module_offset = file_position;
  300.       file_position += length;
  301.       if (write(dirfd, (char *)&lp->dir_entry, sizeof(LD)) != sizeof(LD)) {
  302.          printf("Error writing to directory file\nAlib abandoned\n");
  303.          exit(1);
  304.          }
  305.       }
  306.    /*
  307.     * Close the library files
  308.     */
  309.    close(libfd);
  310.    close(dirfd);
  311.    printf("library is %ld bytes\nAlib complete\n", file_position);
  312.    exit(0);
  313.    }
  314.  
  315.  
  316. /*
  317.  * Main program.
  318.  */
  319. main(argc, argv)
  320. int   argc;
  321. char  *argv[];
  322. {
  323.    int   count;
  324.  
  325.    printf("ALIB Rev. 1.0 \n");
  326.    printf("Amiga Object Module Librarian\n");
  327.    printf("Programmed by Mike Schwartz\n");
  328.    printf("(C)1985 MS Software, all rights reserved\n");
  329.  
  330.    /*
  331.     * check for command line parameters present.
  332.     */
  333.    if (argc < 3)
  334.       help();
  335.    /*
  336.     * setup the option and filenames
  337.     */
  338.    option = argv[1][0];
  339.    strcpy(libname, argv[2]);
  340.    strcpy(dirname, argv[2]);
  341.    strcat(libname, ".lib");
  342.    strcat(dirname, ".dir");
  343.    if (option == 'l' || option == 'L') {
  344.       directory();
  345.       exit(0);
  346.       }
  347.    if (option != 'd' && option != 'D' && option != 'r' && option != 'R')
  348.       help();
  349.    /*
  350.     * Open the library file
  351.     */
  352.    open_library();
  353.    for (count = 3; count < argc; count++) {
  354.       switch(option) {
  355.          case 'd':
  356.          case 'D':
  357.             printf("deleting %s from library\n", argv[count]);
  358.             if (!kill_module(argv[count]))
  359.                printf("%s not defined in library\n", argv[count]);
  360.             else
  361.                printf("deleted.\n");
  362.             break;
  363.          case 'r':
  364.          case 'R':
  365.             kill_module(argv[count]);
  366.             add_module(argv[count]);
  367.             break;
  368.          }
  369.       }
  370.    close_library();
  371.    }
  372.  
  373. directory() {
  374.    LD    d_entry;
  375.    int   count;
  376.    int   bytes;
  377.  
  378.    dirfd = open(dirname, O_RDONLY | O_RAW);
  379.    if (dirfd == -1) {
  380.       printf("%s not found\n", dirname);
  381.       exit(1);
  382.       }
  383.    printf("Directory of library %s\n", libname);
  384.    printf("Module Name                    Size   Offset\n");
  385.    count = bytes = 0;
  386.    while (read(dirfd, (char *)&d_entry, sizeof(LD)) == sizeof(LD)) {
  387.       printf("%-30.30s %-6d %-6d\n", d_entry.object_filename, 
  388.                d_entry.module_size, d_entry.module_offset);
  389.       count++;
  390.       bytes += d_entry.module_size;
  391.       }
  392.    printf("Library consists of %d entries totalling %d bytes\n", count,
  393.             bytes);
  394.    close(dirfd);
  395.    }
  396.  
  397.